package com.luoqiu.cinema.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.luoqiu.cinema.common.BuyMovieParam;
import com.luoqiu.cinema.common.PageParam;
import com.luoqiu.cinema.common.PageResult;
import com.luoqiu.cinema.common.Result;
import com.luoqiu.cinema.eitityExtends.TicketEx;
import com.luoqiu.cinema.entity.Movie;
import com.luoqiu.cinema.entity.MoviePlace;
import com.luoqiu.cinema.entity.TicketUser;
import com.luoqiu.cinema.entity.UserInfo;
import com.luoqiu.cinema.mapper.*;
import com.luoqiu.cinema.util.UserInfoUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class TicketService {

    @Resource
    private MovieMapper movieMapper;
    @Resource
    private MoviePlaceMapper moviePlaceMapper;
    @Resource
    private TicketMapper ticketMapper;
    @Resource
    private TicketUserMapper ticketUserMapper;
    @Resource
    private UserInfoUtil userInfoUtil;

    public Result<PageResult<Movie>> allMovies(PageParam pageParam) {
        PageHelper.startPage(pageParam.getPage(), pageParam.getRows());
        List<Movie> movies = movieMapper.loadAllMovie(pageParam.getKeyword());
        PageInfo<Movie> info = new PageInfo<>(movies);
        PageResult<Movie> pageResult = new PageResult<>();
        pageResult.setData(movies);
        pageResult.setTotal(info.getTotal());
        return Result.success(pageResult);
    }

    @Transactional(rollbackFor = Exception.class)
    public synchronized Result<PageResult<MoviePlace>> allPlace(PageParam pageParam) {
        PageHelper.startPage(pageParam.getPage(), pageParam.getRows());
        List<MoviePlace> moviePlaces = moviePlaceMapper.loadAllPlaceByMovieId(pageParam.getId());
        PageInfo<MoviePlace> pageInfo = new PageInfo<>(moviePlaces);
        PageResult<MoviePlace> pageResult = new PageResult<>();
        pageResult.setData(moviePlaces);
        pageResult.setTotal(pageInfo.getTotal());
        return Result.success(pageResult);
    }

    @Transactional(rollbackFor = Exception.class)
    public synchronized Result<String> buyMovie(BuyMovieParam buyMovieParam) {
        Integer userId = userInfoUtil.getInfo().getId();
        TicketUser tu = ticketUserMapper.loadByUserIdAndParam(userId, buyMovieParam);
        if (null != tu) {
            return Result.fail("已经买过了");
        }
        ticketMapper.updateTotal(buyMovieParam);
        Integer id = ticketMapper.loadId(buyMovieParam.getMovieId(), buyMovieParam.getPlaceId());
        TicketUser ticketUser = new TicketUser();
        ticketUser.setMovieId(buyMovieParam.getMovieId());
        ticketUser.setMoviePlaceId(buyMovieParam.getPlaceId());
        ticketUser.setBuyTime(new Date());
        ticketUser.setLocaltionOrder(buyMovieParam.getLocationOrder());
        ticketUser.setTicketNum(buyMovieParam.getTicketNum());
        ticketUser.setTicketStatus(1);
        ticketUser.setTicketId(id);
        ticketUser.setUserId(userId);
        ticketUserMapper.insertSelective(ticketUser);
        return Result.success("OK");
    }

    public Result<Map<String, List<String>>> getLocation(Integer movieId, Integer placeId) {
        //Integer total = ticketMapper.loadAllLocaltion(movieId, placeId);

        List<TicketUser> ticketUsers = ticketUserMapper.loadAllLocation(movieId, placeId);
        String hasSelect = ticketUsers.stream().map(TicketUser::getLocaltionOrder).collect(Collectors.joining(";"));
        String[] split = hasSelect.split(";");

        List<String> allLocation = getSurplusLocation(4, 5);
        List<String> surplusLocation = allLocation.stream().filter(Objects::nonNull).filter(e -> !Arrays.asList(split).contains(e)).collect(Collectors.toList());
        Map<String, List<String>> resMap = new HashMap<>(3);
        resMap.put("all", allLocation);
        resMap.put("sur", surplusLocation);
        return Result.success(resMap);
    }

    private static List<String> getSurplusLocation(Integer rows, Integer column) {
        List<String> allLocation = new ArrayList<>(rows + column);
        for (int i = 0; i<= rows; i++) {
            for (int j = 1; j <= column; j++) {
                allLocation.add("(" + i + "," + j + ")");
            }
        }
        return allLocation;
    }

    public Result<PageResult<TicketEx>> qry(PageParam pageParam) {
        Integer userId;
        try {
            userId = userInfoUtil.getInfo().getId();
        } catch (Exception e) {
            userId = pageParam.getId();
        }
        PageHelper.startPage(pageParam.getPage(), pageParam.getRows());
        List<TicketEx> ticketExes = ticketUserMapper.loadByUserId(userId);
        PageInfo<TicketEx> pageInfo = new PageInfo<>(ticketExes);
        PageResult<TicketEx> pageResult = new PageResult<>();
        pageResult.setTotal(pageInfo.getTotal());
        pageResult.setData(ticketExes);
        return Result.success(pageResult);
    }

    @Transactional(rollbackFor = Exception.class)
    public void rollback(Integer id) {
        TicketUser ticketUser = ticketUserMapper.selectByPrimaryKey1(id);
        Integer ticketNum = ticketUser.getTicketNum();
        Integer ticketId = ticketUser.getTicketId();
        ticketMapper.updateSurplus(ticketId, ticketNum);
        ticketUserMapper.deleteByPrimaryKey(id);
    }
}
